﻿using S7.Net;
using Servo_Tool.cache;
using Servo_Tool.utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Servo_Tool.client
{
    public class S7NetClient
    {
        private Plc master;
        private readonly string unitNo;
        private readonly string host;
        private readonly int port;
        public bool HasStarted()
        {
            return true;
        }

        public S7NetClient(string unitNo, string host, int port)
        {
            this.unitNo = unitNo;
            this.host = host;
            this.port = port;
        }

        public string ReadData(int dbNumber, int startAdr, byte bitOffset, string varTyp, int length)
        {
            switch (varTyp)
            {
                case "BOOL":
                    object v1 = master.Read(DataType.DataBlock, dbNumber, startAdr, VarType.Bit, length, bitOffset);
                    return v1.ToString();
                case "INT":
                    object v2 = master.Read(DataType.DataBlock, dbNumber, startAdr, VarType.Int, length);
                    return Convert.ToInt32(v2).ToString();
                case "WSTR":
                    byte[] buffer = master.ReadBytes(DataType.DataBlock, dbNumber, startAdr, length);
                    return S7HexUtils.GetStringFromBytes(buffer);
                default:
                    return "";
            }
        }

        public void Start()
        {
            try
            {
                master = new Plc(CpuType.S71200, host, port, 0, 1);
                Connect();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public void Connect()
        {
            
            master.Open();
            if (master.IsConnected)
            {
                Console.WriteLine("连接成功");
            }
            else
            {
                Connect();
            }
        }

        public void WriteData(int dbNumber, int startAdr, int offset, string varTyp, object data)
        {
            try
            {
                switch (varTyp)
                {
                    case "BOOL":
                        master.Write(DataType.DataBlock, dbNumber, startAdr, Convert.ToBoolean(data), offset);
                        break;
                    case "INT":
                        master.Write(DataType.DataBlock, dbNumber, startAdr, Convert.ToInt16(data));
                        break;
                    case "WSTR":
                        master.Write(DataType.DataBlock, dbNumber, startAdr, GetPLCStringByteArray(data.ToString()));
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private byte[] GetPLCStringByteArray(string str)
        {
            byte[] value = Encoding.Default.GetBytes(str);
            byte[] head = new byte[2];
            head[0] = Convert.ToByte(254);
            head[1] = Convert.ToByte(str.Length);
            value = head.Concat(value).ToArray();
            return value;
        }
    }
}
